更新时间:2024-03-27 19:33
Common Lisp,缩写为 CL(不要和缩写同为CL的组合逻辑混淆),是Lisp的众多方言之一,与Scheme合称现代两大Lisp方言,标准由ANSI X3.226-1994定义。它是为了标准化此前众多的Lisp分支而开发的,导致其语言规范和标准长达千页。要注意,它本身并不是一个具体的实现,而是各个Lisp实现所遵循的规范。它操作的数据是动态数据类型,但也可用类型声明来提高效率和增强安全性。
Common Lisp是一个现代的,多重范式的,高性能,可编译的标准化ANSI编程语言。相对于各种嵌入在特定产品中的Lisp方言,例如Emacs Lisp 和 AutoLISP,Common Lisp 是一种通用用途的编程语言。不像很多早期的Lisp,Common Lisp同Scheme一样,变量有作用域。
Common Lisp具有高度灵活性,对象化编程以及快速的框架能力提供优异的支持。同时它还提供强大的宏能力,使编程者在编码时定制自己的应用,并给编程者提供了高度灵活的运行环境,可在运行时修改和调试程序。 其多重范式语言特性还允许编程者选择适当的方法和范式适应编写的应用程序。
Common Lisp 是一种 Lisp; 它使用 前置标识表达式(前标式) 来表示代码和数据。 函数(function)和宏(macro)也以前标式的形式写出,前标式的第一项是函数名或者宏名,就像在这些例子中:
>(+ 2 2) ; 将 2 加上 2, 得 4
; 定义一个函数用来计算一个数的平方:
>(defun square (x) (* x x))
; 执行这个函数:
当求值器遇到一式形如 (F A1 A2...),那么名为 F 的符号被认为是如下之一:
如果 F 是函数名,那么参数 A1, A2,...,An 被从左到右依次求值,然后找到函数定义,并把这些值作为参数调用这个函数。如果F是特殊操作符,那么A1,A2,...,An是否会被求值以及求值顺序会由操作符决定,比如
>(if oddp x) ; 在x是奇数时返回t,否则返回nil
上述代码在求值时会在求值if后先求值条件式(第一个参数),条件式求值结果为t,则求值第二个参数,否则不求值第二个参数,直接求值第三个参数。
宏则是可以让用户完全自定义求值规则,换句话说,写一种新的语言。
Common Lisp 是一个多重范式编程语言,这表现在:
支持各种编程技术:过程编程,函数编程和面向对象编程。
动态数据类型,但也可用类型声明来提高效率和增强安全性。
可以通过一些标准特性来扩展,例如 Lisp宏(程序自我进行的编译时代码重排 (compile-time code rearrangement accomplished by the program itself))和 阅读器宏(赋予用户自定义的保留字以特殊意义的符号扩展 (extension of syntax to give special meaning to characters reserved for users for this purpose))。
Common Lisp 拥有丰富的数据类型。
数据类型
数字类型包括整数,分数,浮点数,和复数。Common Lisp 使用 bignum 来表示任意长度和精度的数值。分数类型精确地表示分数,这是很多语言都不具备的能力。 Common Lisp 自动将数值转换成适当的类型。
Common Lisp 字符 类型并不仅仅是 ASCII 字符,这是因为 Lisp 在 ASCII 出现前就存在了。 一些现代的实现默认使用Unicode字符。
内名(Symbol)类型是Lisp语言共有的,而在其它语言中就较少见。一个内名是一个数据对象的唯一命名。与其它语言中的标识符(Identifier)类似,Lisp中的内名可以用作变量名,但它们也是可以独立使用的一种数据对象。一般来说,对一个内名求值时会得到以该内名为名的变量的值,但也有例外:形如:foo的关键词内名的值就是它本身,而内名T和NIL则分别表示布尔逻辑真与布尔逻辑假。
数据结构
Common Lisp 的顺序类型包括链表(lists),向量(vectors), 位向量(bit-vectors),和字符串(strings)。
同任何其他的Lisp一样,Common Lisp中的基本数据单位称作 首.尾(conses,有时候叫做cons cells 或者 pairs)。一个 首.尾 就是拥有两个槽的数据结构,这两个槽被称作 首(car) 和 尾(cdr)。
函数
在 Common Lisp 里, 函数 是一种数据类型。 例如,可以写出以一个函数作为参数的函数,同时函数的返回值也可以是函数--这种函数称为高阶函数。这就让用函数描述非常通用的操作成为可能。
Common Lisp 的库高度依赖这种高阶函数。 例如,sort(排序)函数用一个 比较操作符 作为他的参数之一。这样一来,这个函数就不但可以用来对任何类型的数据排序,还可以根据一个关键码对数据结构排序。
>(sort (list 5 2 6 3 1 4) #'>)
; 使用函数 >来排序,也就是按大小从大排到小排序
; 结果是 (6 5 4 3 2 1).
>(sort (list 9 a) '(3 b) '(4 c))
#'(lambda (x y) (< (car x) (car y)))
; 根据子链表的第一个,按照从小到大排序
; 结果是 ((3 b) (4 c) (9 a)).
这一求值模型对于函数很简单。
定义函数
宏 defun 用来定义函数。 函数定义给出了函数名,参数名和函数体:
>(defun square (x)(* x x))
函数定义中可以包括 “声明”,它可以指示编译器优化设置或参数的数据类型等。还可以在函数定义中包括“文档字符串”(vdocstrings),Lisp 系统用它们形成交互式文档:
>(defun square x)
(declare (number x) (optimize (speed 3) (debug 0) (safety 1)))
(* x x)
匿名函数用 lambda 表达式定义。Lisp 编程频繁使用高阶函数,以匿名函数作为其参数的作法十分有效。
还有一些有关于函数定义和函数操作的运算符。如,操作符 compile 可以用来重新编译函数。(一些Lisp系统默认下在解释器里运行函数,除非指示编译它;其他Lisp系统在函数输入时即被编译。)
函数名字空间
函数的名字空间与数据变量的名字空间是分离的。这是 Common Lisp 和Scheme编程语言的一个重要不同之处。 在函数名字空间定义名字的操作符包括 defun,flet,和 labels。
要用函数名把函数作为参数传给另一个函数,必须使用function特殊操作符,通常简略为 #'。上文第一个 sort 的例子中,为了引用在函数名字空间名为 > 的函数,使用了代码 #'>。
为函数提供分离的名字空间是否有益是 Lisp 社区不断争论的主题之一,常被称为 “Lisp-1 与 Lisp-2 辩论”。这些名称出现于Richard P. Gabriel 和 Kent Pitman 1998 年的一篇论文,文中广泛的比较了这两种方法。
Common Lisp 是由一份技术规范定义而不是被某一种具体实现定义(前者的例子有Ada语言和C语言,后者有Perl语言)。 存在很多种实现,语言标准详细阐明了可能导致合理歧义的内容。
另外,各种实现试图引入库包来提供标准没有提及的功能。可移植的自由软件库提供了各种特性,Common-Lisp net 和 Common Lisp Open Code Collection 项目。
Common Lisp 设计为由增量编译器实现。 优化编译的标准声明(例如内联函数)已进入语言规范的计划。 大多数Lisp实现将函数编译成原生的机器语言。其他的编译器编译为通用二进制码,虽有损软件运行效率但通用性好。由于Lisp提供了交互式的提示符以及函数增量式的依次编译,很多人误会为Lisp是纯解释语言。
一些基于Unix的实现,例如CLISP,可以作为脚本解释器使用;因此,系统可以像调用Perl 或者Unix shell解释器一样透明的调用它。
免费的可重发布实现:
商业实现
在这里Franz, Inc.,Xanalys Corp.,Digitool, Inc.,Corman Technologies and Scieneer Pty Ltd.。
Common Lisp 被用于很多成功的商业系统,最著名的(毫无疑问要归功于Paul Graham的推广)要数Yahoo! 商店的站点。其他值得一提的例子有:
Orbitz,以旅行书籍为主的站点
Mirai,Izware LLC's fully integrated 2d/3d computer graphics content creation suite that features what is almost universally regarded as the best polygonal modeler in the industry, an advanced IK/FK and non-linear animation system (later popularized by such products as Sega's Animanium and Softimage XSI, respectively), and advanced 2d and 3d painting. It is used in major motion pictures(most famously in New Line Cinema's Lord of the Rings), video games and military simulations.
Piano,一个用Lisp写的商业的航空期前期设计包以及与它的竞争对手的比较
Xanalys Corp.的调查软件,被全球的警察,安全部门和防止诈骗服务部门采用
Genworks International的多用途说明语言(GDL),是一个基于CL的开发工具,用来创建基于web的工程,设计和商业应用
也有很多成功的开源应用用Common Lisp写成,例如:
Applicative Common Lisp,a full-featured theorem prover for a subset of Common Lisp.
Maxima,a sophisticated computer algebra system。
Compo,a language allowing complex musical structures to be described in a natural way.
同样,Common Lisp也被许多政府和非盈利组织采用。NASA中的例子有:
SPIKE,the Hubble Space Telescope planning and scheduling system.
Remote Agent,winner of the 1999 NASA Software of the Year Award.